/*
 *  KeypadKeyMapper.cpp
 *  Dictionary
 *
 *  Created by Rune Laugesen on 21/09/10.
 *  Copyright 2010 Copenhagen University. All rights reserved.
 *
 */

#include <iostream>
#include <sstream>
#include <cmath>
#include "KeypadKeyMapper.h"

using namespace std;

KeypadKeyMapper::KeypadKeyMapper() 
{
    BuildAlphabet();
}

void KeypadKeyMapper::BuildAlphabet()
{
    _alphabet.insert ( pair<char, string>('\'', "1") );
    _alphabet.insert ( pair<char, string>('\"', "1") );
    _alphabet.insert ( pair<char, string>('-', "1") );
    _alphabet.insert ( pair<char, string>('`', "1") );
    _alphabet.insert ( pair<char, string>('.', "1") );
    _alphabet.insert ( pair<char, string>(',', "1") );
    _alphabet.insert ( pair<char, string>('!', "1") );
    _alphabet.insert ( pair<char, string>('?', "1") );
    _alphabet.insert ( pair<char, string>('a', "2") );
    _alphabet.insert ( pair<char, string>('b', "2") );
    _alphabet.insert ( pair<char, string>('c', "2") );
    _alphabet.insert ( pair<char, string>('d', "3") );
    _alphabet.insert ( pair<char, string>('e', "3") );
    _alphabet.insert ( pair<char, string>('f', "3") );
    _alphabet.insert ( pair<char, string>('g', "4") );
    _alphabet.insert ( pair<char, string>('h', "4") );
    _alphabet.insert ( pair<char, string>('i', "4") );
    _alphabet.insert ( pair<char, string>('j', "5") );
    _alphabet.insert ( pair<char, string>('k', "5") );
    _alphabet.insert ( pair<char, string>('l', "5") );
    _alphabet.insert ( pair<char, string>('m', "6") );
    _alphabet.insert ( pair<char, string>('n', "6") );
    _alphabet.insert ( pair<char, string>('o', "6") );
    _alphabet.insert ( pair<char, string>('p', "7") );
    _alphabet.insert ( pair<char, string>('q', "7") );
    _alphabet.insert ( pair<char, string>('r', "7") );
    _alphabet.insert ( pair<char, string>('s', "7") );
    _alphabet.insert ( pair<char, string>('t', "8") );
    _alphabet.insert ( pair<char, string>('u', "8") );
    _alphabet.insert ( pair<char, string>('v', "8") );
    _alphabet.insert ( pair<char, string>('w', "8") );
    _alphabet.insert ( pair<char, string>('x', "9") );
    _alphabet.insert ( pair<char, string>('y', "9") );
    _alphabet.insert ( pair<char, string>('z', "9") );
    _alphabet.insert ( pair<char, string>('0', "0") );
    _alphabet.insert ( pair<char, string>('1', "1") );
    _alphabet.insert ( pair<char, string>('2', "2") );
    _alphabet.insert ( pair<char, string>('3', "3") );
    _alphabet.insert ( pair<char, string>('4', "4") );
    _alphabet.insert ( pair<char, string>('5', "5") );
    _alphabet.insert ( pair<char, string>('6', "6") );
    _alphabet.insert ( pair<char, string>('7', "7") );
    _alphabet.insert ( pair<char, string>('8', "8") );
    _alphabet.insert ( pair<char, string>('9', "9") );
}

void KeypadKeyMapper::MapDictionary()
{
    for (vector<string>::iterator it = _dictionary.begin(); it != _dictionary.end(); it++) {
        string word = (*it);
        string keys = StringToKeys(word);
        _mappedDictionary.insert(pair<string, string>(keys, (*it)));
    }
}

vector<string> KeypadKeyMapper::GetMappings(string word)
{
    vector<string> mappings;
    pair<multimap<string, string>::iterator, multimap<string, string>::iterator> mmit;
    string keys = StringToKeys(word);
    multimap<string, string>::iterator it;
    
    mmit = _mappedDictionary.equal_range(keys);
        
    for (multimap<string, string>::iterator it = mmit.first; it != mmit.second; ++it)
    {
        mappings.push_back(((string)(*it).second));
    }
    
    
    return mappings;
}

vector<string> KeypadKeyMapper::GetMatchedMappings(string prefixkeys)
{
    vector<string> mappings;
    
    for (multimap<string, string>::iterator it = _mappedDictionary.begin(); it != _mappedDictionary.end(); ++it)
    {
        if (((string)(*it).first).compare(0, prefixkeys.length(), prefixkeys) == 0)
        {
            mappings.push_back(((string)(*it).second));
        }
    }
    return mappings;
}

vector<string> KeypadKeyMapper::GetNextBestMappings(string keys, int startkey)
{
    vector<string> mappings;
    vector<string> matchedmappings;
    
    for (int i = startkey; i < keys.length(); i++)
    {
        string subkeys;
        subkeys = keys.substr(0, keys.length() - i);
        matchedmappings = this->GetMatchedMappings(subkeys);
        mappings.insert(mappings.end(), matchedmappings.begin(), matchedmappings.end());
        if (mappings.empty())
            break;
    }
    return mappings;
}

string KeypadKeyMapper::StringToKeys(string word)
{
    string keys = "";
    map<char, string>::iterator it;

    for (int i = 0; i < word.length(); i++)
    {
        it = _alphabet.find(tolower(word[i]));
        if (it == _alphabet.end())
        {
            keys += '1';
            continue;
        }
        keys += (*it).second;
    }
    
    return keys;
}

